﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Forms;
using System.Linq;
//using Microsoft.Data.Schema.ScriptDom.Sql;
//using Microsoft.Data.Schema.ScriptDom;

namespace Nizm0.QOT.Library.Objects
{
    [Serializable]
    public class Result: System.Runtime.Serialization.ISerializable
    {
        private string _file = string.Empty;
        private bool _windowopen = true;
        private bool _finished = true;
        private bool _started = false;
        private bool _saved = true;
        private bool _manuallychanged = false;

        private Library.Objects.ProcedureInfo _parent;
        [NonSerialized]
        private ArrayList _tableList = new ArrayList();
        [NonSerialized]
        private ArrayList _arraylistAllResult = new ArrayList();
        [NonSerialized]
        private ArrayList _arraylistFilteredResult = new ArrayList();
        [NonSerialized]
        private ArrayList _arraylistTMPResult = new ArrayList();

        private List<Library.Objects.Query> _resultList;

        /// <summary>
        /// list of queries for loocking procedures
        /// </summary>
        private List<string> _querySerchList = new List<string>();

        //[NonSerialized]
        //private Library.Objects.ProjectSettings _projectSettings;

        private StringBuilder _result = new StringBuilder();

        private string QueryForLokingProcedure;
        [NonSerialized]
        private List<Thread> _threadList = new List<Thread>();
        [NonSerialized]
        private System.Threading.Timer _myThrTimer;
        [NonSerialized]
        private Stopwatch _serchStopWatch = new Stopwatch();

        //[NonSerialized]
        //private static int EM_LINEINDEX = 0xbb;
        //[DllImport("user32.dll")]
        //extern static int SendMessage(IntPtr hwnd, int message, int wparam, int lparam);

        #region Delegates

        public event ChangeStatusEvetHendler StatusChange;

        public event ErrorEventHandler ErrorEvent;

        public delegate void DelegateLookingProcedureEnds(Library.Objects.ProcedureInfo procedure);
        public event DelegateLookingProcedureEnds LookingProcedureEnds;
        public event DelegateLookingProcedureEnds LookingProcedureStart;
        public delegate void DelegateLookingProcedureUpdate(Library.Objects.ProcedureInfo procedure, Library.Objects.ProcedureInfo.Status status);
        public event DelegateLookingProcedureUpdate LookingProcedureUpdate;
        public delegate void DelegateCloseResultWindow(Library.Objects.ProcedureInfo procedure);
        public event DelegateCloseResultWindow ResultWindowClose;

        public delegate void DelegateInStartMethod(object sender, EventArgs e);
        public event DelegateInStartMethod BeforeStartMethod;
        public event DelegateInStartMethod EndedStartMethod;

        delegate void DelegateQueryPrint(string printingresult);
        event DelegateQueryPrint QueryPrint;

        internal delegate void DelegateNewQueryFound(object sender, ReturnFullRowEventHandler e);
        internal event DelegateNewQueryFound NewQueryFound;

        public event FinishedSearchObjectEventHandler FinishedSearchObject;

        #endregion

        #region Properties

        public string File
        {
            get { return _file; }
            set
            {
                _file = value;
                //base.TabPag.ToolTipText = _file;
            }
        }
        public bool IsOpen
        {
            get { return _windowopen; }
            //set { _windowopen = value; }
        }
        public bool Finished
        {
            get { return _finished; }
        }
        public bool Started
        {
            get { return _started; }
            set { _started = value; }
        }
        public Library.Objects.ProcedureInfo LookingProcedure
        {
            get { return _parent; }
            //set { LookingPocedure = value; }
        }
        public bool Saved
        {
            get { return _saved; }
        }
        public bool ManuallyChanged
        {
            get { return _manuallychanged; }
        }

        public List<Library.Objects.Query> ResultList
        {
            get { return _resultList; }
            set { _resultList = value; }
        }

        public StringBuilder ResultString
        {
            get
            {
                if (!object.Equals(_resultList, _parent.ResultList))
                    _resultList = _parent.ResultList;
                if (_resultList != null && _resultList.Count != 0)
                {
                    _result.Length = 0;
                    foreach (Query txt in _resultList)
                        PrintResult(txt.QueryString);
                }
                return _result;
            }
            set { _result = value; }
        }

        public Library.Objects.ProcedureInfo Parent
        {
            get { return _parent; }
            set { _parent = value; }
        }
        //} 
        #endregion

        public override string ToString()
        {
            return base.ToString();
        }

        #region Constructors
        //public Result(Library.Objects.ProcedureInfo procedure, Form parent)
        //{
        //    _resultList = procedure.ResultList;
        //    //this.Deactivate += new EventHandler(DeactivateMethod);
        //    //_projectSettings = project;
        //    _parent = procedure;
        //    //this.Text = string.Format(_lookingProcedure.Name);
        //    _parent.IsOpen = true;

        //    //if (GetFromSQL.StatusChange == null)
        //    Library.Scripts.GetFromSQL.OnSetStatusChangeEvent(new Library.ChangeStatusEvetHendler(OnChangeStatus));
        //    Library.Scripts.GetFromSQL.SetErrorEvent(new Library.ErrorEventHandler(OnErrorEvent));
        //}

        public Result(ProcedureInfo parent)
        {
            _parent = parent;
            _resultList = parent.ResultList;
        }

        public Result()
        {
        }
        #endregion

        #region Methods

        public void Save(object sender, EventArgs e)
        {
            //if ((LookingPocedure.Found <= 0 && !this._manuallychanged)||!this._manuallychanged)
            if (this._saved || this._resultList.Count == 0)
            {
                OnChangeStatus("No results for " + _parent.Name + ", I refuse to save.");
            }
            else
            {
                //_file = ProjectSettings.ProjectLocation + "\\Queries\\" + LookingPocedure;
                if (_file != string.Empty)
                {
                    //ProjectSettings.ProjectLocation + "\\Queries\\" + LookingPocedure;
                    //LookingPocedure.
                }
                else
                {
                    try
                    {
                        if (string.IsNullOrWhiteSpace(Parent.ResultFile))
                        {
                            if (!Directory.Exists(Library.Objects.ProjectSettings.Instance.ProjectResultsLocation)) Directory.CreateDirectory(Library.Objects.ProjectSettings.Instance.ProjectResultsLocation);
                            _file = Library.Objects.ProjectSettings.Instance.ProjectResultsLocation + _parent + ".txt";
                        }
                        else
                            _file = Parent.ResultFile;

                        using (StreamWriter strw = new StreamWriter(_file))
                        {
                            strw.Write(_result);
                        }

                        Parent.ResultFile = _file;
                    }
                    catch (Exception ex)
                    {
                        if (ErrorEvent != null) ErrorEvent(this, ex);
                    }
                }
                Serialize();
                IsSaved();
                OnChangeStatus("Procedure \"" + _parent.Name + "\" was saved as " + _file + ".");
            }
        }

        //public void Load(List<Query> QueryList)
        //{
        //    if (_resultList == null || _resultList.Count == 0)
        //        _resultList = QueryList;
        //}

        /// <summary>
        /// It begin backgroundWorker for looking procedure.
        /// </summary>
        public void Start(Library.Objects.ProcedureInfo.Status Status = Objects.ProcedureInfo.Status.Started)
        {
            _started = true;
            _finished = false;

            //TimerCallback tcb = timer_Tick;
            _myThrTimer = new System.Threading.Timer((TimerCallback)timer_Tick, new AutoResetEvent(false), 0, 1);
            _serchStopWatch.Reset();
            _serchStopWatch.Start();
            NotSaved();
            OnLookingProcedureUpdate(_parent, Status);
            
            _parent.StartTime = System.DateTime.Now;
            
            ThreadPool.QueueUserWorkItem(new WaitCallback(FindQueries));
        }

        private void timer_Tick(Object stateInfo)
        {
            try
            {
                //if (this.Visible)
                //{
                //    if (this.InvokeRequired)
                //        this.BeginInvoke((MethodInvoker)delegate
                //        {
                //            toolStripStatusLabel_Time.Text = _serchStopWatch.Elapsed.ToString();
                //        });
                //    else
                //    {
                //        toolStripStatusLabel_Time.Text = _serchStopWatch.Elapsed.ToString();
                //    }
                //}
            }
            catch
            {
            }
        }

        public DataSet FilterMethod(DataSet list, string filtercolumnname)
        {
            int counter = 0;
            int count = 0;
            int progress = 0;
            DataSet tmplist = new DataSet();
            DataTable tmpTable = list.Tables[0].Clone();
            foreach (DataTable table in list.Tables)
            {
                foreach (DataColumn column in table.Columns)
                {
                    if (column.ColumnName == filtercolumnname)
                        foreach (DataRow row in table.Rows)
                        {
                            _arraylistAllResult.Add(row[column].ToString());
                            counter++;
                            progress = (counter * 100) / table.Rows.Count;

                            //listBox_result.Items.Add(text);
                            char[] delimiters = new char[] { '\r', '\n' };
                            string[] tmptexttab;
                            tmptexttab = row[column].ToString().Split(delimiters, StringSplitOptions.RemoveEmptyEntries);
                            if ((row[column].ToString().Contains(_parent.Name + " ")) || (row[column].ToString().Contains(_parent.Name + "\n")) || (row[column].ToString().Contains(_parent.Name + "\r\n")) || (row[column].ToString().EndsWith(_parent.Name)))
                            {
                                bool niezawiera = true;
                                //TODO uaktualnieć filtrowanie, filtruje również po nazwie procedury
                                string pattern;
                                foreach (string tmptext in tmptexttab)
                                {
                                    if (row[column].ToString().Contains("--"))
                                    {
                                        if (tmptext.ToString().IndexOf(_parent.Name) > tmptext.ToString().IndexOf("--"))
                                        {
                                            foreach (string tmpFilterText in Library.Objects.ProjectSettings.Instance.FilterList)
                                            {//[^a-z^A-Z^0-9]+|
                                                pattern = "[\n\r\t .,]*" + tmpFilterText + "[\n\r\t .,]*";//"update\\s\\[*[a-zA-Z]*";
                                                if (Regex.IsMatch(tmptext.ToString(), pattern, RegexOptions.IgnoreCase))
                                                {
                                                    niezawiera = false;
                                                }
                                                //if (row[column].ToString().ToUpper().Contains(tmpFilterText.ToUpper()))
                                                //{
                                                //    notcontains = false;
                                                //}
                                            }
                                        }
                                        else
                                            niezawiera = false;
                                    }
                                    else
                                    {
                                        //string tmptest = row[column].ToString();
                                        foreach (string tmpText in Library.Objects.ProjectSettings.Instance.FilterList)
                                        {
                                            pattern = "[\n\r\t .,]*" + tmpText + "[\n\r\t .,]*";//"update\\s\\[*[a-zA-Z]*";
                                            string pattern1 = "[\n\r\t .,]*" + tmpText + ".*" + _parent.Name + "[\n\r\t .,]*";
                                            if (Regex.IsMatch(row[column].ToString(), pattern, RegexOptions.IgnoreCase))
                                            {
                                                if (Regex.IsMatch(row[column].ToString(), pattern1, RegexOptions.IgnoreCase))
                                                    niezawiera = false;
                                            }
                                            //if (row[column].ToString().ToUpper().Contains(tmpFilterText.ToUpper()))
                                            //{
                                            //    notcontains = false;
                                            //    break;
                                            //}
                                        }
                                    }
                                }
                                if (niezawiera)
                                {
                                    DataRow nrow = tmpTable.NewRow();
                                    nrow.ItemArray = row.ItemArray;
                                    tmpTable.Rows.Add(nrow);
                                    count++;
                                    //this.BeginInvoke((MethodInvoker)delegate
                                    //{
                                    //    PrintResult(progress, row[column].ToString());
                                    //});
                                }
                            }
                        }
                }
                tmplist.Tables.Add(tmpTable);
                if (count >= Library.Objects.ProjectSettings.Instance.Queries)
                {
                    break;
                }
                //Thread.Sleep(1000);
            }

            return tmplist;
        }

        public DataSet FilterMethodCopy(DataSet list, string filtercolumnname)
        {
            int counter = 0;
            int count = 0;
            int progress = 0;
            DataSet tmplist = new DataSet();
            DataTable tmpTable = list.Tables[0].Clone();
            foreach (DataTable table in list.Tables)
            {
                foreach (DataColumn column in table.Columns)
                {
                    if (column.ColumnName == filtercolumnname)
                        foreach (DataRow row in table.Rows)
                        {
                            _arraylistAllResult.Add(row[column].ToString());
                            counter++;
                            progress = (counter * 100) / table.Rows.Count;

                            //listBox_result.Items.Add(text);
                            char[] delimiters = new char[] { '\r', '\n' };
                            string[] tmptexttab;
                            tmptexttab = row[column].ToString().Split(delimiters, StringSplitOptions.RemoveEmptyEntries);
                            if ((row[column].ToString().Contains(_parent.Name + " ")) || (row[column].ToString().Contains(_parent.Name + "\n")) || (row[column].ToString().Contains(_parent.Name + "\r\n")) || (row[column].ToString().EndsWith(_parent.Name)))
                            {
                                bool niezawiera = true;
                                //TODO Nie aktualne uaktualnieć filtrowanie, filtruje również po nazwie procedury
                                string pattern;
                                foreach (string tmptext in tmptexttab)
                                {
                                    if (row[column].ToString().Contains("--"))
                                    {
                                        if (row[column].ToString().IndexOf(_parent.Name) > row[column].ToString().IndexOf("--"))
                                        {
                                            foreach (string tmpText in Library.Objects.ProjectSettings.Instance.FilterList)
                                            {//[^a-z^A-Z^0-9]+|
                                                pattern = "[\n\r\t .,]*" + tmpText + "[\n\r\t .,]+";//"update\\s\\[*[a-zA-Z]*";
                                                if (Regex.IsMatch(row[column].ToString(), pattern, RegexOptions.IgnoreCase))
                                                {
                                                    niezawiera = false;
                                                }
                                                //if (row[column].ToString().ToUpper().Contains(tmpFilterText.ToUpper()))
                                                //{
                                                //    notcontains = false;
                                                //}
                                            }
                                        }
                                        else
                                            niezawiera = false;
                                    }
                                    else
                                    {
                                        string tmptest = row[column].ToString();
                                        foreach (string tmpText in Library.Objects.ProjectSettings.Instance.FilterList)
                                        {
                                            pattern = "[\n\r\t .,]*" + tmpText + "[\n\r\t .,]+";//"update\\s\\[*[a-zA-Z]*";
                                            if (Regex.IsMatch(row[column].ToString(), pattern, RegexOptions.IgnoreCase))
                                            {
                                                niezawiera = false;
                                            }
                                            else
                                            {

                                            }
                                            //if (row[column].ToString().ToUpper().Contains(tmpFilterText.ToUpper()))
                                            //{
                                            //    notcontains = false;
                                            //    break;
                                            //}
                                        }
                                    }
                                }
                                if (niezawiera)
                                {
                                    DataRow nrow = tmpTable.NewRow();
                                    nrow.ItemArray = row.ItemArray;
                                    tmpTable.Rows.Add(nrow);
                                    count++;
                                    //this.BeginInvoke((MethodInvoker)delegate
                                    //{
                                    //    PrintResult(progress, row[column].ToString());
                                    //});
                                }
                            }
                        }
                }
                tmplist.Tables.Add(tmpTable);
                if (count >= Library.Objects.ProjectSettings.Instance.Queries)
                {
                    break;
                }
                //Thread.Sleep(1000);
            }

            return tmplist;
        }

        private void FindQueries(Object stateInfo)
        {
            List<Exception> err = new List<Exception>();
            try
            {
                OnBeforeStart();

#if DEBUG
                //Thread.Sleep(5000);  
#endif
                if (!_parent.StartFromTheLatestData)
                {
                    _arraylistFilteredResult.Clear();
                    _arraylistAllResult.Clear();
                    _result.Length = 0;
                }
                else
                {
                }

                ArrayList list = new ArrayList();

                Library.Scripts.GetFromSQL findQueriesInSql = new Library.Scripts.GetFromSQL(Library.Objects.ProjectSettings.Instance.Queries);
                //List<Library.Objects.Query> resultList;// = new List<Objects.Query>();
                findQueriesInSql.ReturnSingleQuery += new Scripts.GetFromSQL.DelegateReturnSingleQuery(FindQueriesInSQL_ReturnSingleQueryEvent);
                findQueriesInSql.ReturnFullRow += new Scripts.GetFromSQL.DelegateReturnFullRow(FindQueriesInSQL_ReturnFullRow);
                findQueriesInSql.FinishedSearchObject += new FinishedSearchObjectEventHandler(FindQueriesInSQL_FinishedSearchObject);


                _arraylistFilteredResult.AddRange(findQueriesInSql.FindQueries(Library.Objects.ProjectSettings.Instance, _parent, FilterMethod, out _resultList, err));

                SaveAllInTEMP();
                Save(this, new EventArgs());

                QueryForLokingProcedure = findQueriesInSql.QueryForLookingProcedure;
                OnLookingProcedureUpdate(_parent, Library.Objects.ProcedureInfo.Status.Ended);
                //throw new Exception("test");
            }
            catch (Exception ex)
            {
                if (ErrorEvent != null) ErrorEvent(this, ex);

                OnLookingProcedureUpdate(_parent, Library.Objects.ProcedureInfo.Status.Error);
                //MessageBox.Show(ex.ToString());
            }
            finally
            {
                //if (EwentLookingProcedureUpdate != null)
                //    EwentLookingProcedureUpdate(_lookingProcedure, Library.Objects.ProcedureInfo.Status.Ended);
                LoockingProcessEnd(Library.Objects.ProcedureInfo.Status.Ended);

                OnChangeStatus("Searching for the procedure " + _parent.Name + " ends.");

                OnEnded();
            }
        }

        private void FindQueriesInSQL_FinishedSearchObject(object sender, FinishedSearchObjectEventArgs e)
        {
            FinishedSearchObject(sender, e);
        }

        private void OnLookingProcedureUpdate(Library.Objects.ProcedureInfo procedure, Library.Objects.ProcedureInfo.Status status)
        {
            if (LookingProcedureUpdate != null)
                LookingProcedureUpdate(procedure, status);
        }

        private bool FindQueriesInSQL_ReturnSingleQueryEvent(object sender, string e)
        {
            char[] delimiters = new char[] { '\r', '\n' };
            string[] tmptexttab;
            tmptexttab = e.ToString().Split(delimiters, StringSplitOptions.RemoveEmptyEntries);
            if ((e.ToString().Contains(_parent.Name + " ")) || (e.ToString().Contains(_parent.Name + "\n")) || (e.ToString().Contains(_parent.Name + "\r\n")) || (e.ToString().EndsWith(_parent.Name)))
            {
                bool notcontains = true;
                //TODO uaktualnieć filtrowanie, filtruje również po nazwie procedury
                string pattern;
                foreach (string tmptext in tmptexttab)
                {
                    if (e.ToString().Contains("--"))
                    {
                        if (tmptext.ToString().IndexOf(_parent.Name) > tmptext.ToString().IndexOf("--"))
                        {
                            foreach (string tmpFilterText in Library.Objects.ProjectSettings.Instance.FilterList)
                            {//[^a-z^A-Z^0-9]+|
                                pattern = "[\n\r\t .,]*" + tmpFilterText + "[\n\r\t .,]*";//"update\\s\\[*[a-zA-Z]*";
                                if (Regex.IsMatch(tmptext.ToString(), pattern, RegexOptions.IgnoreCase))
                                {
                                    notcontains = false;
                                }
                                //if (row[column].ToString().ToUpper().Contains(tmpFilterText.ToUpper()))
                                //{
                                //    notcontains = false;
                                //}
                            }
                        }
                        else
                            notcontains = false;
                    }
                    else
                    {
                        //string tmptest = row[column].ToString();
                        foreach (string tmpText in Library.Objects.ProjectSettings.Instance.FilterList)
                        {
                            pattern = "[\n\r\t .,]*" + tmpText + "[\n\r\t .,]*";//"update\\s\\[*[a-zA-Z]*";
                            string pattern1 = "[\n\r\t .,]*" + tmpText + ".*" + _parent.Name + "[\n\r\t .,]*";
                            if (Regex.IsMatch(e.ToString(), pattern, RegexOptions.IgnoreCase))
                            {
                                if (Regex.IsMatch(e.ToString(), pattern1, RegexOptions.IgnoreCase))
                                    notcontains = false;
                            }
                            //if (row[column].ToString().ToUpper().Contains(tmpFilterText.ToUpper()))
                            //{
                            //    notcontains = false;
                            //    break;
                            //}
                        }
                    }
                }
                if (notcontains)
                {
                    Parse(e);
                    PrintResult(e);
                    NotSaved();
#if DEBUG
                    OnChangeStatus(e);
#endif
                    return true;
                }
            }
            //Parse(e);
            //PrintResult(0, e);
            return false;
        }

        private void FindQueriesInSQL_ReturnFullRow(object sender, ReturnFullRowEventHandler e)
        {
            OnNewQueryFound(this, e);
        }

        public List<string> Parse(string sql)
        {
            //TSql100Parser parser = new TSql100Parser(false);
            //IScriptFragment fragment;
            //IList<ParseError> errors;
            //fragment = parser.Parse(new StringReader(sql), out errors);
            //if (errors != null && errors.Count > 0)
            //{
            //    List<string> errorList = new List<string>();
            //    foreach (var error in errors)
            //    {
            //        errorList.Add(error.Message);
            //    }
            //    return errorList;
            //}
            return null;
        }

        private void PrintResult(string str)
        {
            try
            {
                StringBuilder tmpresult = new StringBuilder();
                OnQueryPrintEvent(str);
                bool isdeclare = str.IndexOf("declare", StringComparison.CurrentCultureIgnoreCase) >= 0 ? true : false;

                if (_parent.KnownVersionList.Count == 0)
                {
                    if (isdeclare)
                    {
                        tmpresult.Append("go");
                        tmpresult.AppendLine();
                        tmpresult.Append("dbcc freeproccache dbcc dropcleanbuffers");
                        tmpresult.AppendLine();
                        tmpresult.Append("go");
                        tmpresult.AppendLine();
                        tmpresult.Append(str);
                        //tmpresult.AppendLine();
                        //tmpresult.Append("go");
                        tmpresult.AppendLine();
                        tmpresult.AppendLine();
                    }
                    else
                    {
                        tmpresult.Append("go");
                        tmpresult.AppendLine();
                        tmpresult.Append("dbcc freeproccache dbcc dropcleanbuffers");
                        tmpresult.AppendLine();
                        tmpresult.Append("go");
                        tmpresult.AppendLine();
                        tmpresult.Append(str);
                        tmpresult.AppendLine();
                        //tmpresult.Append("go");
                        tmpresult.AppendLine();
                    }
                }
                else
                {
                    //ProcedureSQLInfo tmpproc = LookingPocedure.ProcSzczegOLD == null ? LookingPocedure.ProcSzczegNEW : LookingPocedure.ProcSzczegOLD;
                    if (isdeclare)
                        _parent.KnownVersionList[0].Parent.ActionInProcedure |= Library.Objects.Procedure.EnumActionInProcedure.Declare;
                    else
                        _parent.KnownVersionList[0].Parent.ActionInProcedure &= ~Library.Objects.Procedure.EnumActionInProcedure.Declare;

                    if (_parent.KnownVersionList[0].Parent.ActionInProcedure.HasFlag(Library.Objects.Procedure.EnumActionInProcedure.Insert)
                        || _parent.KnownVersionList[0].Parent.ActionInProcedure.HasFlag(Library.Objects.Procedure.EnumActionInProcedure.Update)
                        || _parent.KnownVersionList[0].Parent.ActionInProcedure.HasFlag(Library.Objects.Procedure.EnumActionInProcedure.Delete))
                    {

                        tmpresult.Append("go");
                        tmpresult.AppendLine();
                        tmpresult.Append("dbcc freeproccache dbcc dropcleanbuffers");
                        tmpresult.AppendLine();
                        tmpresult.Append("go");
                        tmpresult.AppendLine();
                        tmpresult.Append("begin tran");
                        tmpresult.AppendLine();
                        tmpresult.Append("go");
                        tmpresult.AppendLine();
                        tmpresult.Append(str);
                        tmpresult.AppendLine();
                        tmpresult.Append("go");
                        tmpresult.AppendLine();
                        tmpresult.Append("rollback tran");
                        tmpresult.AppendLine();
                        tmpresult.AppendLine();
                    }
                    else
                    {
                        tmpresult.Append("go");
                        tmpresult.AppendLine();
                        tmpresult.Append("dbcc freeproccache dbcc dropcleanbuffers");
                        tmpresult.AppendLine();
                        tmpresult.Append("go");
                        tmpresult.AppendLine();
                        tmpresult.Append(str);
                        //tmpresult.AppendLine();
                        //tmpresult.Append("go");
                        tmpresult.AppendLine();
                        tmpresult.AppendLine();
                    }

                }
                //listBox_Result.Items.Add(str);
                //richTextBox_Tresc.Text += tmpresult.ToString();

                _result.Append(tmpresult);
                NotSaved();
                //toolStripProgressBar.Value = progress;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
                if (ErrorEvent != null)
                    ErrorEvent(this, ex);
            }
        }

        private void OnBeforeStart()
        {
            if (BeforeStartMethod != null)
            {
                BeforeStartMethod(this, new EventArgs());
            }
        }

        private void OnEnded()
        {
            if (EndedStartMethod != null)
            {
                EndedStartMethod(this, new EventArgs());
            }
        }

        private void OnQueryPrintEvent(string str)
        {
            if (QueryPrint != null)
                QueryPrint(str);
        }

        private void OnNewQueryFound(object sender, ReturnFullRowEventHandler e)
        {
            if (NewQueryFound != null)
                NewQueryFound(sender, e);
        }

        private void OnLookingProcedureEnds()
        {
            if (LookingProcedureEnds != null)
                LookingProcedureEnds(_parent);
        }

        private void LoockingProcessEnd(Objects.ProcedureInfo.Status status)
        {
            this._finished = true;
            this._started = false;

            SaveInTEMP();
            //Properties.tmpserver.Default.ProjectLocalization
            _parent.EndTime = System.DateTime.Now;
            _parent.Found = _arraylistFilteredResult.Count;
            OnLookingProcedureEnds();

            //timer_Tick(sender, e);

            if (_serchStopWatch.IsRunning)
                _serchStopWatch.Stop();
            _myThrTimer.Dispose();
            //Serialize();
            //Serialize1();
        }

        public void Abort()
        {
            foreach (Thread tmpthr in _threadList)
            {
                if (tmpthr.IsAlive)
                {
                    tmpthr.Abort();
                    LoockingProcessEnd(Objects.ProcedureInfo.Status.Canceled);
                    //EwentLookingProcedureUpdate(_lookingProcedure, Objects.ProcedureInfo.Status.Canceled);
                }
            }
        }

        private int CountCharInText(char ch, ref string text)
        {
            IEnumerable<char> l = from c in text where c == ch select ch;
            return l.Count();
        }

        /// <summary>
        /// Read result from saved file or temp file
        /// </summary>
        /// <param name="procedure"></param>
        public void OpenFileWithResult(Library.Objects.ProcedureInfo procedure)
        {
            try
            {
                DataTable tmpTable = new DataTable();
                if (System.IO.File.Exists(Library.Objects.ProjectSettings.Instance.ProjectLocation + "\\" + procedure.Name + ".txt"))
                {
                    _file = Library.Objects.ProjectSettings.Instance.ProjectLocation + "\\" + procedure.Name + ".txt";
                }
                else
                {
                    if (System.IO.File.Exists(Library.Objects.ProjectSettings.Instance.ProjectResultsLocation + procedure.Name + ".txt"))
                    {
                        _file = Library.Objects.ProjectSettings.Instance.ProjectResultsLocation + procedure.Name + ".txt";
                    }
                    else
                        if (System.IO.File.Exists(Library.Objects.ProjectSettings.Instance.ProjectLocation + "\\Temp\\" + procedure.Name + ".txt"))
                        {
                            _file = Library.Objects.ProjectSettings.Instance.ProjectLocation + "\\Temp\\" + procedure.Name + ".txt";
                        }
                }
                if (_file.Length > 0 && !(DeSerialize(ref tmpTable) && tmpTable.Columns.Contains("TextData")))
                {
                    StreamReader txt = new StreamReader(_file, true);

                    OpenFileWithResult(txt, procedure);
                }
                else
                {
                    foreach (DataRow dtRow in tmpTable.Rows)
                    {
                        //listBox_Result.Items.Add(dtRow["TextData"]);
                        PrintResult(dtRow["TextData"].ToString());
                    }
                }
                //richTextBox_Tresc.Text = _result.ToString();
                OnLookingProcedureUpdate(_parent, Library.Objects.ProcedureInfo.Status.Opened);
            }
            catch (Exception ex)
            {
                if (ErrorEvent != null)
                    ErrorEvent(this, ex);
                //MessageBox.Show(ex.ToString(), "Warning!!");
            }
            finally
            {
                IsSaved();
                //base.TabPag.ToolTipText = _file;
            }
        }

        public void OpenFileWithResult(StreamReader file, Library.Objects.ProcedureInfo procedure)
        {
            int count = 0;
            string tmpline = string.Empty;
            ArrayList tmparraylist = new ArrayList();
            //int count = 0;
            string tmpquery = string.Empty;
            //string firstmath = string.Empty;
            //string nextmath=string.Empty;
            string[] stringtable = { "declare", "set", "select", procedure.Name };

            while (!file.EndOfStream)
            {
                tmpline = file.ReadLine();
                while ((CountCharInText('\'', ref tmpline) % 2) > 0)
                    tmpline += Environment.NewLine + file.ReadLine().Trim();
                //if (tmpline.Contains("'"))
                tmparraylist.Add(tmpline);
                if (tmpline.Contains(procedure.Name)) count++;
                //listBox_Result.Items.Add(tmpline);

                //richTextBox_Tresc.AppendText(tmpline.Trim() + Environment.NewLine);

            }
            file.Close();
            if (count > 0)
            {
                double d = tmparraylist.Count / count;
                int severity = Convert.ToInt32(Math.Round(d, 0));
                int i = 1;
                foreach (string tmpstr in tmparraylist)
                {
                    for (int j = 0; j < stringtable.Length; j++)//string patern in stringtable)
                    {
                        if (Regex.IsMatch(tmpstr, stringtable[j], RegexOptions.IgnoreCase))
                        {
                            tmpline = tmpstr.Trim();
                            if (tmpstr.Contains("dbcc freeproccache dbcc dropcleanbuffers"))
                            {
                                tmpline = tmpstr.Remove(tmpstr.IndexOf("dbcc freeproccache dbcc dropcleanbuffers", 0), "dbcc freeproccache dbcc dropcleanbuffers".Length).Trim();
                            }
                            tmpquery += tmpline + "\t";
                        }
                    }
                    if (i++ == d)
                    {
                        i = 1;
                        //listBox_Result.Items.Add(tmpquery.Trim());
                        PrintResult(tmpquery.Trim());
                        tmpquery = string.Empty;
                    }
                }
            }

            if (procedure.Found != count)
            {
                procedure.Found = count;
                OnLookingProcedureUpdate(_parent, Library.Objects.ProcedureInfo.Status.Opened);
            }
        }

        /// <summary>
        /// Ask if you want to save the result
        /// </summary>
        /// <returns></returns>
        private DialogResult AskForSave()
        {
            DialogResult odp = MessageBox.Show("Save changes?", "Results " + _parent.Name, MessageBoxButtons.YesNoCancel, MessageBoxIcon.Exclamation);
            if (odp == DialogResult.Yes)
                Save(null, null);
            return odp;
        }

        /// <summary>
        /// Sets the status window on the "not saved"
        /// </summary>
        private void NotSaved()
        {
            if (_saved)
            {
                _saved = false;
                //this.Text = "*" + this.Text;
                //if (_tabPag != null)
                //    _tabPag.Text = this.Text;
            }
        }

        /// <summary>
        /// Sets the status window on the "saved"
        /// </summary>
        private void IsSaved()
        {
            if (!_saved)
            {
                _saved = true;
                _manuallychanged = false;
                //this.Text = this.Text.Remove(0, 1);
                //if (_tabPag != null)
                //    _tabPag.Text = this.Text;
            }
        }

        /// <summary>
        /// Saving result in a temporary file
        /// </summary>
        private void SaveInTEMP()
        {
            Library.Objects.ProjectSettings.Instance.ProjectLocation.ToString();
            //string test = ProjectSettings.ProjectLocation;
            if (!string.IsNullOrWhiteSpace(Library.Objects.ProjectSettings.Instance.ProjectLocation))
            {
                if (!Directory.Exists(Library.Objects.ProjectSettings.Instance.ProjectLocation + "\\Temp"))
                {
                    Directory.CreateDirectory(Library.Objects.ProjectSettings.Instance.ProjectLocation + "\\Temp");
                }
                StreamWriter sw = new StreamWriter(Library.Objects.ProjectSettings.Instance.ProjectLocation + "\\Temp\\" + _parent.Name + ".txt");
                sw.Write(_result);
                sw.Close();
            }
        }

        /// <summary>
        /// Saving not filtered result in a temporary file
        /// </summary>
        private void SaveAllInTEMP()
        {
            //string test = ProjectSettings.ProjectLocation;
            if (!string.IsNullOrWhiteSpace(Library.Objects.ProjectSettings.Instance.ProjectLocation))
            {
                if (!Directory.Exists(Library.Objects.ProjectSettings.Instance.ProjectLocation + "\\Temp\\All\\"))
                {
                    Directory.CreateDirectory(Library.Objects.ProjectSettings.Instance.ProjectLocation + "\\Temp\\All\\");
                }
                StreamWriter sw = new StreamWriter(Library.Objects.ProjectSettings.Instance.ProjectLocation + "\\Temp\\All\\" + _parent.Name + ".txt");
                foreach (string tmp in _arraylistAllResult)
                {
                    sw.WriteLine(tmp);
                }
                sw.Close();
            }
        }

        private void OnErrorEvent(object obj, Exception ex)
        {
            if (ErrorEvent != null)
            {
                ErrorEvent(obj, ex);
            }
        }

        private void OnChangeStatus(string str)
        {
            if (StatusChange != null)
            {
                StatusChange(str);
            }
        }

        private void OnChangeStatus(Object obj, string str)
        {
            if (obj.GetType() == typeof(Library.Objects.Table))
            {

                Library.Objects.Table tmptable = (Library.Objects.Table)obj;
                StatusChange(str);

            }
        }
        #endregion


        private void toolStripButton_Start_Click(object sender, EventArgs e)
        {
            Start(Library.Objects.ProcedureInfo.Status.Force);
        }

        private void Serialize()
        {
            //if (dataGridView1.DataSource != null)
            //{
            //    if (!Directory.Exists(Library.Objects.ProjectSettings.Instance.ProjectLocation + "\\Queries\\AdditionalData\\")) Directory.CreateDirectory(Library.Objects.ProjectSettings.Instance.ProjectLocation + "\\Queries\\AdditionalData\\");
            //    StreamWriter str = new StreamWriter(Library.Objects.ProjectSettings.Instance.ProjectLocation + "\\Queries\\AdditionalData\\" + _lookingProcedure.Name + ".xml", false, Encoding.UTF8);
            //    try
            //    {
            //        Type testtype = dataGridView1.DataSource.GetType();
            //        ((DataTable)dataGridView1.DataSource).WriteXml(str, XmlWriteMode.WriteSchema);
            //    }
            //    catch (Exception ex)
            //    {
            //        OnErrorEvent(this, ex);
            //    }
            //    finally
            //    {
            //        str.Close();
            //    }
            //}
        }

        private bool DeSerialize(ref DataTable table)
        {
            //bool ok = false;
            //if (System.IO.File.Exists(Library.Objects.ProjectSettings.Instance.ProjectLocation + "\\Queries\\AdditionalData\\" + _lookingProcedure.Name + ".xml"))
            //{
            //    StreamReader str = new StreamReader(Library.Objects.ProjectSettings.Instance.ProjectLocation + "\\Queries\\AdditionalData\\" + _lookingProcedure.Name + ".xml", true);
            //    try
            //    {
            //        //DataTable table;
            //        table.ReadXml(str);
            //        dataGridView1.DataSource = table;
            //        if (dataGridView1.Columns.Contains("TextData") && dataGridView1.Columns.Contains("SourceTable"))
            //            if (dataGridView1.InvokeRequired)
            //            {
            //                dataGridView1.Invoke((MethodInvoker)delegate
            //                {
            //                    dataGridView1.Columns["TextData"].DisplayIndex = 0;
            //                    dataGridView1.Columns["SourceTable"].DisplayIndex = 1;
            //                });
            //            }
            //            else
            //            {
            //                dataGridView1.Columns["TextData"].DisplayIndex = 0;
            //                dataGridView1.Columns["SourceTable"].DisplayIndex = 1;
            //            }
            //        ok = true;
            //    }
            //    catch (Exception ex)
            //    {
            //        OnErrorEvent(this, ex);
            //        ok = false;
            //    }
            //    finally
            //    {
            //        str.Close();
            //    }

            //}
            return true;
        }

        #region ISerializable Members

        public void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
        {
            //info.AddValue("
        }

        #endregion

        private void toolStripButton_QueryList_Click(object sender, EventArgs e)
        {
            Form frmQueryList = new Form();
            ListBox queryListBox = new ListBox();
            queryListBox.DataSource = _resultList;
            frmQueryList.Controls.Add(queryListBox);
            queryListBox.Dock = DockStyle.Fill;
            //frmQueryList.ShowDialog(this);
        }

        private void dataGridView1_DataError(object sender, DataGridViewDataErrorEventArgs e)
        {
            //OnErrorEvent(sender, e.Exception);
        }
    }
}